#pragma once
#include <iostream>
#include <Winsock2.h>
#include <WS2tcpip.h>
#include <mutex>
#include <string>
#include <map>
#include <memory>
#include <thread>
#include <vector>
#include <queue>
#include <condition_variable>
#include "global.h"
#pragma comment(lib,"ws2_32.lib")

using namespace std;

// 前向声明
class NetworkConnectionManager;
class SessionManager;
class MessageProcessor;
class DatabaseServer;

// 客户端连接信息
struct ClientInfo {
    SOCKET socket;
    int sessionId;
    string address;
    bool isAuthenticated;
    string username;
};

// �������ӹ����� - ����socket���ӵĽ�����ά��
class NetworkConnectionManager {
public:
    NetworkConnectionManager();
    ~NetworkConnectionManager();

    bool initialize();
    bool startListening(int port);
    SOCKET acceptConnection();
    void closeConnection(SOCKET socket);
    void shutdown();

private:
    SOCKET listenSocket;
    bool isInitialized;

    bool initWinsock();
    void cleanupWinsock();
};

// �Ự������ - �����û��Ự�Ĺ�������֤
class SessionManager {
public:
    SessionManager();

    int createSession(SOCKET socket, const string& address);
    bool authenticateUser(int sessionId, const string& username, const string& password);
    string getUsername(int sessionId);
    bool isAuthenticated(int sessionId);
    void removeSession(int sessionId);

private:
    map<int, shared_ptr<ClientInfo>> sessions;
    mutex sessionMutex;
    int nextSessionId;
};

// ��Ϣ������ - ������Ϣ�ķ��ͺͽ���
class MessageProcessor {
public:
    MessageProcessor();

    bool sendMessage(SOCKET socket, const string& message);
    string receiveMessage(SOCKET socket);
    bool processAuthenticationRequest(SOCKET socket, string& username, string& password);

private:
    static const int BUFFER_SIZE = 1024;
};

// SQL������� - ����SQL����Ľ�����ִ��
class SQLCommandHandler {
public:
    static string executeCommand(const string& sqlCommand, const string& username);

private:
    static string formatErrorMessage(const string& error, int line, int column);
};

// �����ݿ�������� - Э���������
class DatabaseServer {
public:
    DatabaseServer();
    ~DatabaseServer();

    bool start(int port = server_my_port);
    void stop();

private:
    unique_ptr<NetworkConnectionManager> connectionManager;
    unique_ptr<SessionManager> sessionManager;
    unique_ptr<MessageProcessor> messageProcessor;

    vector<thread> clientThreads;
    bool isRunning;
    mutex serverMutex;

    void handleClient(SOCKET clientSocket, const string& clientAddress);
    bool performClientAuthentication(SOCKET socket, int sessionId);
    void processClientCommands(SOCKET socket, int sessionId);
};